package fr.xgouchet.wedding.client.view;

import java.util.ArrayList;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HTMLTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

import fr.xgouchet.wedding.client.i18n.Constants;
import fr.xgouchet.wedding.client.i18n.Messages;
import fr.xgouchet.wedding.client.presenter.GuestsListPresenter.Display;
import fr.xgouchet.wedding.shared.model.Guest;

/**
 * UI Widget to display a Guests List
 * 
 * @author x.gouchet
 * 
 */
public class GuestsListView extends Composite implements Display {

	/**
	 * Default Constructor
	 */
	public GuestsListView() {
		// main panel
		HorizontalPanel main = new HorizontalPanel();
		initWidget(main);

		// create scroll container
		ScrollPanel scroll = new ScrollPanel();
		mList = new FlexTable();
		scroll.addStyleName("scrollPanel");
		mList.addStyleName("guestsList");

		// create right side of the page
		VerticalPanel right = new VerticalPanel();
		FlowPanel buttons = new FlowPanel();
		buttons.addStyleName("buttonsBar");

		// create buttons
		mAddButton = new Button(Constants.I18N.buttonAdd());
		mEditButton = new Button(Constants.I18N.buttonEdit());
		mEditButton.setEnabled(false);
		mDeleteButton = new Button(Constants.I18N.buttonDelete());
		mDeleteButton.setEnabled(false);

		// Create guest info container
		mInfo = new SimplePanel();
		mInfo.addStyleName("guestInfo");

		// final assembly
		scroll.add(mList);
		buttons.add(mAddButton);
		buttons.add(mEditButton);
		buttons.add(mDeleteButton);
		right.add(buttons);
		right.add(mInfo);
		main.add(scroll);
		main.add(right);

		mSelected = -1;
	}

	/**
	 * @see Display#getAddButton()
	 */
	public HasClickHandlers getAddButton() {
		return mAddButton;
	}

	/**
	 * @see Display#getEditButton()
	 */
	public HasClickHandlers getEditButton() {
		return mEditButton;
	}

	/**
	 * @see Display#getDeleteButton()
	 */
	public HasClickHandlers getDeleteButton() {
		return mDeleteButton;
	}

	/**
	 * @see Display#getClickedRow(ClickEvent)
	 */
	public int getClickedRow(ClickEvent event) {
		int selectedRow = -1;
		HTMLTable.Cell cell = mList.getCellForEvent(event);

		if (cell != null) {
			selectedRow = cell.getRowIndex();
			updateSelected(selectedRow);
		}
		return selectedRow;
	}

	/**
	 * @see Display#getList()
	 */
	public HasClickHandlers getList() {
		return mList;
	}

	/**
	 * @see Display#displayGuest(Guest)
	 */
	public void displayGuest(Guest g) {
		if (g == null) {
			// disable edit and delete button
			mEditButton.setEnabled(false);
			mDeleteButton.setEnabled(false);
			mInfo.clear();
			return;
		}

		// enable edit and delete buttons
		mEditButton.setEnabled(true);
		mDeleteButton.setEnabled(true);

		// display guest in the GuestView
		StringBuilder sb = new StringBuilder();

		// Display name
		sb.append("<div class=\"");
		sb.append(g.isMan() ? "man" : "woman");
		sb.append("\">");
		sb.append("<h2>");
		sb.append("<img src=\"");
		sb.append(status(g.getStatus()));
		sb.append(".png\" alt=\"status\"/> &nbsp; ");
		sb.append(g.getDisplayName());
		sb.append("</h2>\n");

		// Display Group
		if (g.getGroup().length() == 0) {
			sb.append("<p>\n");
			sb.append(Messages.I18N.noGroup());
			sb.append("</p>\n");
		} else {
			sb.append("<h4>");
			sb.append(Constants.I18N.labelGroup());
			sb.append(" : ");
			sb.append(g.getGroup());
			sb.append("</h4>\n");
		}

		// display roles
		if (g.getRoles().length() != 0) {
			sb.append("<h4>");
			sb.append(Constants.I18N.labelRoles());
			sb.append("</h4>\n<ul>\n");
			String[] roles = g.getRoles().split(",");
			for (String role : roles) {
				sb.append("<li>");
				sb.append(role);
				sb.append("</li>\n");
			}
			sb.append("</ul>\n");
		}

		// display company
		if (g.getComingWith().length() > 0) {
			sb.append("<p>\n");
			sb.append(Messages.I18N.comingWith(g.getComingWith()));
			sb.append("</p>\n");
		}

		// display position (link)
		sb.append("<p>\n");
		if ((g.getTable() == -1) || (g.getSeat() == -1)) {
			sb.append(Messages.I18N.noSeating());
			sb.append("<br/>");
		}
		sb.append("<a href=\"#guests-seating\">");
		sb.append(Messages.I18N.seeSeating());
		sb.append("</a>\n</p>\n");

		sb.append("</div>");

		mInfo.clear();
		mInfo.add(new HTML(sb.toString()));
	}

	/**
	 * @see Display#setData(ArrayList)
	 */
	public void setData(ArrayList<String> data) {
		mList.removeAllRows();

		for (int i = 0; i < data.size(); ++i) {
			mList.setText(i, 0, data.get(i));
		}
	}

	/**
	 * @see Display#asWidget()
	 */
	public Widget asWidget() {
		return this;
	}

	/**
	 * Updates the selected row
	 * 
	 * @param row
	 *            the row to select
	 */
	private void updateSelected(int row) {
		if (row != -1) {
			if (mSelected != -1)
				mList.getRowFormatter().removeStyleName(mSelected, "selected");
			mSelected = row;
			mList.getRowFormatter().addStyleName(mSelected, "selected");
		}
	}

	/**
	 * @param status
	 *            the status code (-1; 0 or 1)
	 * @return the name of the corresponding status
	 */
	private String status(int status) {
		if (status == 0)
			return "invalid";
		else if (status == 1)
			return "valid";
		else
			return "unknown";
	}

	/** the list of Cells */
	private FlexTable mList;

	/** the current guest info */
	private SimplePanel mInfo;

	/** the current selected cell */
	private int mSelected;

	/** the Add button */
	private Button mAddButton;

	/** the Edit button */
	private Button mEditButton;

	/** The Delete button */
	private Button mDeleteButton;
}
